Make ballon and backend drivers fail gracefully if they are unable to initialize
authorIan.Campbell@xensource.com <Ian.Campbell@xensource.com>
Wed, 9 Aug 2006 10:27:28 +0000 (11:27 +0100)
committerIan.Campbell@xensource.com <Ian.Campbell@xensource.com>
Wed, 9 Aug 2006 10:27:28 +0000 (11:27 +0100)
due to missing hypervisor support.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
linux-2.6-xen-sparse/drivers/xen/netback/netback.c

index 95117b92ccd97315449ee0b4a4c6d96b81e03819..08ad6fd2b661bf8c460b1dc0bd3805ddc244be99 100644 (file)
@@ -563,10 +563,14 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
                set_xen_guest_handle(reservation.extent_start, &gmfn);
                ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
                                           &reservation);
+               if (ret == -ENOSYS)
+                       goto err;
                BUG_ON(ret != 1);
        } else {
                ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
                                          dealloc_pte_fn, NULL);
+               if (ret == -ENOSYS)
+                       goto err;
                BUG_ON(ret);
        }
        current_pages -= 1UL << order;
@@ -583,6 +587,11 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
                set_page_count(page + i, 1);
 
        return page;
+
+ err:
+       free_pages(vstart, order);
+       balloon_unlock(flags);
+       return NULL;
 }
 
 void balloon_dealloc_empty_page_range(
index ace6dbcc37cf7952f0a86d09a076081252beaff8..00f5785dd8d5c78f8c88a263764ad3a39744ca26 100644 (file)
@@ -518,6 +518,19 @@ static int __init blkif_init(void)
                return -ENODEV;
 
        mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
+       extern unsigned long alloc_empty_foreign_map_page_range(
+               unsigned long pages);
+       mmap_vstart = (unsigned long)
+               alloc_empty_foreign_map_page_range(mmap_pages);
+#else /* ! ia64 */
+       page = balloon_alloc_empty_page_range(mmap_pages);
+       if (page == NULL)
+               return -ENOMEM;
+       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+#endif
+
        pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
                                        blkif_reqs, GFP_KERNEL);
        pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
@@ -534,16 +547,6 @@ static int __init blkif_init(void)
 
        blkif_interface_init();
        
-#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
-       extern unsigned long alloc_empty_foreign_map_page_range(
-               unsigned long pages);
-       mmap_vstart = (unsigned long)
-               alloc_empty_foreign_map_page_range(mmap_pages);
-#else /* ! ia64 */
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       BUG_ON(page == NULL);
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-#endif
        printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
               __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
        BUG_ON(mmap_vstart == 0);
index deb9e6193359774789faad7dcbaa53a07bddc631..329701ffe0fb604a4998b260b010eeab59d4b0b5 100644 (file)
@@ -709,30 +709,19 @@ static void make_response(blkif_t *blkif, unsigned long id,
 /******************************************************************
  * misc small helpers
  */
-/* FIXME: Return ENOMEM properly on failure to allocate additional reqs. */
-static void req_increase(void)
+static int req_increase(void)
 {
        int i, j;
        struct page *page;
        unsigned long flags;
+       int ret;
 
        spin_lock_irqsave(&pending_free_lock, flags);
 
+       ret = -EINVAL;
        if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
                goto done;
 
-       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
-                                       blkif_reqs, GFP_KERNEL);
-       pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
-                                       mmap_pages, GFP_KERNEL);
-
-       if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
-               kfree(pending_reqs[mmap_alloc]);
-               kfree(pending_addrs[mmap_alloc]);
-               WPRINTK("%s: out of memory\n", __FUNCTION__); 
-               goto done;
-       }
-
 #ifdef __ia64__
        extern unsigned long alloc_empty_foreign_map_page_range(
                unsigned long pages);
@@ -740,7 +729,11 @@ static void req_increase(void)
                alloc_empty_foreign_map_page_range(mmap_pages);
 #else /* ! ia64 */
        page = balloon_alloc_empty_page_range(mmap_pages);
-       BUG_ON(page == NULL);
+       ret = -ENOMEM;
+       if (page == NULL) {
+               printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__);
+               goto done;
+       }
 
        /* Pin all of the pages. */
        for (i=0; i<mmap_pages; i++)
@@ -751,6 +744,23 @@ static void req_increase(void)
        mmap_start[mmap_alloc].mpage = page;
 
 #endif
+
+       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
+                                       blkif_reqs, GFP_KERNEL);
+       pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
+                                       mmap_pages, GFP_KERNEL);
+
+       ret = -ENOMEM;
+       if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
+               kfree(pending_reqs[mmap_alloc]);
+               kfree(pending_addrs[mmap_alloc]);
+               WPRINTK("%s: out of memory\n", __FUNCTION__); 
+               ret = -ENOMEM;
+               goto done;
+       }
+
+       ret = 0;
+
        DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
                __FUNCTION__, blkif_reqs, mmap_pages, 
               mmap_start[mmap_alloc].start);
@@ -774,7 +784,7 @@ static void req_increase(void)
        DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
  done:
        spin_unlock_irqrestore(&pending_free_lock, flags);
-
+       return ret;
 }
 
 static void mmap_req_del(int mmap)
@@ -1394,7 +1404,13 @@ static int __init blkif_init(void)
                return -ENODEV;
 
        INIT_LIST_HEAD(&pending_free);
-        for(i = 0; i < 2; i++) req_increase();
+        for(i = 0; i < 2; i++) {
+               ret = req_increase();
+               if (ret)
+                       break;
+       }
+       if (i == 0)
+               return ret;
 
        tap_blkif_interface_init();
 
index 4de5a9cb0b6a65d89efab0a99be91543e1fbaacf..d15332109390c375a73776aa0ba45de4390ea2fb 100644 (file)
@@ -1306,7 +1306,9 @@ static int __init netback_init(void)
        net_timer.function = net_alarm;
     
        page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
-       BUG_ON(page == NULL);
+       if (page == NULL)
+               return -ENOMEM;
+
        mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
 
        for (i = 0; i < MAX_PENDING_REQS; i++) {